﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraSplashScreen;
using FileManager_Client.BusinessLogic;
using FileManager_Client.BusinessLogic.FileManagerUserService;
using FileManager_Client.PresentationLayer.Common;
using FileManager_Client.PresentationLayer.Properties;
using FileManager_Client.Utility;

namespace FileManager_Client.PresentationLayer.NewUi
{
    public partial class LoginLoading : SplashScreen
    {
        #region Form Constructor
        private LoginForm _loginForm;
        private readonly UserService _userService;
        private readonly FileService _fileService;
        private BackgroundWorker loginPictureWorker;
        private System.Timers.Timer timer;
        public LoginLoading(LoginForm loginForm)
        {
            InitializeComponent();
            _loginForm = loginForm;
            _userService = new UserService();
            _fileService = new FileService();
            Login();
            Shown += LoginLoading_Shown;
        }

        void LoginLoading_Shown(object sender, EventArgs e)
        {
            timer = new System.Timers.Timer();
            timer.Elapsed += timer_Elapsed;
            timer.Interval = 500;
            timer.Start();
            //loginPictureWorker = new BackgroundWorker {WorkerSupportsCancellation = true};
            //loginPictureWorker.DoWork += loginPictureWorker_DoWork;
            //loginPictureWorker.RunWorkerAsync();
        }
        int currentPic = 2;
        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            var picName = "loading_";
            if (currentPic > 11)
                currentPic = 1;
            try
            {
                pictureEdit2.Invoke((EventHandler)delegate
                {
                    pictureEdit2.Image =
                        (Image)
                        Resources.ResourceManager.GetObject(picName + currentPic);
                    pictureEdit2.Update();
                });
            }
            catch
            {  
                timer.Stop();
            }
            currentPic++;
        }
        #endregion

        #region Overrides

        public override void ProcessCommand(Enum cmd, object arg)
        {
            base.ProcessCommand(cmd, arg);
        }

        #endregion

        #region Public Property
        public enum SplashScreenCommand
        {
        }
        #endregion

        #region Login Event
        private void Login()
        {
            if (string.IsNullOrEmpty(_loginForm.LoginName) || string.IsNullOrEmpty(_loginForm.LoginPass))
            {
                Hide();
                XtraMessageBox.Show(GlobalString.System_Exception_String.InputNullLoginStr, GlobalString.System_Exception_String.MbxErrorStr, MessageBoxButtons.OK, MessageBoxIcon.Information);
                _loginForm.Show();
                return;
            }
            var firstOrDefault = Dns.GetHostAddresses(Dns.GetHostName()).FirstOrDefault(x => x.AddressFamily.Equals(AddressFamily.InterNetwork));
            var loginArgs = new UserLoginArgs
            {
                UserNamek__BackingField = _loginForm.LoginName,
                UserPassk__BackingField = CryptographyGlobal.Md5Encrypt(_loginForm.LoginPass),
                LoginIpk__BackingField = firstOrDefault == null ? "" : firstOrDefault.ToString()
            };
            Lb_LoginMessage.Text = GlobalString.System_Config_String.LoadingPleaseWaitStr;
            var loginBackgroundWorker = new BackgroundWorker();
            loginBackgroundWorker.DoWork += loginBackgroundWorker_DoWork;
            loginBackgroundWorker.RunWorkerAsync(loginArgs);
        }

        private static object LockLb_message = new object();
        void loginBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var loginArgs = e.Argument as UserLoginArgs;
            if (null == loginArgs)
            {
                BeginInvoke((EventHandler)delegate
                {
                    Hide();
                    //XtraMessageBox.Show(message,
                    //                    GlobalString.System_Exception_String.MbxErrorStr,
                    //                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                    _loginForm.Show();
                });
                return;
            }
            var loginResult = _userService.SyncLoginService(loginArgs);
            if(!string.IsNullOrEmpty(loginResult.Error))
            {
                AsynShowMessage(loginResult.Error);
                return;
            }
            var messageStr = ResultEnumMessage(loginResult.Result.ResultExceptionk__BackingField);
            if (!(string.IsNullOrEmpty(messageStr)))
                AsynShowMessage(messageStr);
            else
            {
                var updateInfoResult = _userService.GetLastVersion();
                var currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
                if (null != updateInfoResult && !updateInfoResult.ApplicationVersion.Equals(currentVersion,StringComparison.InvariantCulture))
                {
                    Invoke((EventHandler) delegate
                                              {
                                                  Hide();
                                                  var updateForm = new UpdateInfomation(updateInfoResult);
                                                  updateForm.ShowDialog();
                                              });
                }
                else
                {
                    CacheGlobal.Add(GlobalString.System_Config_String.UserSession, loginResult.Result);
                    Lb_LoginMessage.Invoke((EventHandler)delegate
                    {
                        Lb_LoginMessage.Text =
                            GlobalString.System_Config_String.
                                LoginPassLoadingStr;
                    });
                    var companyCollectionResult = _userService.SyncGetCompanyService();
                    messageStr = ResultEnumMessage(companyCollectionResult.Result.ResultExceptionk__BackingField);
                    if (!(string.IsNullOrEmpty(messageStr)))
                        AsynShowMessage(messageStr);
                    else
                    {
                        CacheGlobal.Add(GlobalString.System_Config_String.CompanyCollectionCache, companyCollectionResult.Result);
                        Lb_LoginMessage.Invoke((EventHandler)delegate
                        {
                            Lb_LoginMessage.Text =
                                GlobalString.System_Config_String.
                                    LoginPassLoadingFolderStr;
                        });
                        var folderCollectionResult = _userService.SyncGetFolderService();
                        messageStr = ResultEnumMessage(folderCollectionResult.Result.ResultExceptionk__BackingField);
                        if (!(string.IsNullOrEmpty(messageStr)))
                            AsynShowMessage(messageStr);
                        else
                        {
                            CacheGlobal.Add(GlobalString.System_Config_String.FolderCollectionCache, folderCollectionResult.Result);
                            Lb_LoginMessage.Invoke((EventHandler)delegate
                            {
                                Lb_LoginMessage.Text =
                                    GlobalString.System_Config_String.
                                        LoginPassLoadingFolderRoleStr;
                            });
                            var folderRoleCollectionResult = _userService.SyncGetFolderRoleService();
                            messageStr = ResultEnumMessage(folderRoleCollectionResult.Result.ResultExceptionk__BackingField);
                            if (!(string.IsNullOrEmpty(messageStr)))
                                AsynShowMessage(messageStr);
                            else
                            {
                                CacheGlobal.Add(GlobalString.System_Config_String.FolderRoleCollectionCache, folderRoleCollectionResult.Result);
                                var departmentSizeCollection = _fileService.GetDepartmentSizeCollection();
                                CacheGlobal.Add(GlobalString.System_Config_String.DepartmentSizeCollectionCache, departmentSizeCollection);
                                BeginInvoke((EventHandler)delegate
                                {
                                    if (null != timer)
                                        timer.Stop();
                                    UserLocalFile.CheckUserFolder();
                                    UserLocalFile.ClearUserLocalAppConfig();
                                    if (_loginForm.IsRemeberPass || _loginForm.IsAutoLogin)
                                    {
                                        var autoLoginObject = new AutoLoginObject();
                                        if (_loginForm.IsRemeberPass)
                                            autoLoginObject.AutoLogin =
                                                AutoLoginEnum.RemeberPass;
                                        if (_loginForm.IsAutoLogin)
                                            autoLoginObject.AutoLogin =
                                                AutoLoginEnum.AutoLogin;
                                        autoLoginObject.PassWord = _loginForm.LoginPass;
                                        autoLoginObject.UserName = _loginForm.LoginName;
                                        UserLocalFile.SaveUserAppConfig(autoLoginObject);
                                    }
                                    Hide();
                                    _loginForm.ClearLoginInfo();
                                    var mainForm = new FileManagerMain(_loginForm);
                                    mainForm.Show();
                                });
                            }
                        }
                    }
                }
            }
        }
        #endregion

        #region Public method
        private void AsynShowMessage(string message)
        {
            if (!IsHandleCreated)
                CreateHandle();
            Invoke((EventHandler) delegate
                                           {
                                               Hide();
                                               XtraMessageBox.Show(message,
                                                                   GlobalString.System_Exception_String.MbxErrorStr,
                                                                   MessageBoxButtons.OK, MessageBoxIcon.Error);
                                               _loginForm.Show();
                                           });
        }

        private string ResultEnumMessage(BaseExceptionEnum exceptionEnum)
        {
            var result = string.Empty;
            switch (exceptionEnum)
            {
                case BaseExceptionEnum.GetCompanyCollectionException:
                    result = GlobalString.System_Exception_String.GetCompanyCollectionExceptionStr;
                    break;
                case BaseExceptionEnum.LogicException:
                    result = GlobalString.System_Exception_String.LogicExceptionStr;
                    break;
                case BaseExceptionEnum.UserNameOrPassError:
                    result = GlobalString.System_Exception_String.UserNameOrPassErrorStr;
                    break;
                case BaseExceptionEnum.AccountLock:
                    result = GlobalString.System_Exception_String.AccountLockStr;
                    break;
                case BaseExceptionEnum.GetFolderCollectionException:
                    result = GlobalString.System_Exception_String.GetFolderCollectionExceptionStr;
                    break;
                case BaseExceptionEnum.GetFolderRoleCollectionException:
                    result = GlobalString.System_Exception_String.GetFolderRoleCollectionExceptionStr;
                    break;
            }
            return result;
        }
        #endregion
    }
}